package com.gitee.generator.universal.common;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Map;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.text.CharSequenceUtil;
import lombok.extern.slf4j.Slf4j;
import cn.hutool.core.io.FileUtil;
import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import freemarker.template.Version;

/**
 * FreeMarkerInit
 * @date 2020-08-19 11:24
 * @author wsx
 */
@Slf4j
public final class FreeMarkerUtil {
    /** 模版配置 */
    private static Configuration cfg = null;
    /** 字符串配置 */
    private static Configuration cfg4StringTemplate = null;
    /** 构造器 */
    public FreeMarkerUtil() {
        super();
    }

    /**
     * getInstance
     */
    public static FreeMarkerUtil getInstance(final Version freeMarkerVersion, final String templateDir) throws IOException {
        // 配置类
        cfg = new Configuration(freeMarkerVersion);
        cfg.setDirectoryForTemplateLoading(new File(templateDir));
        cfg.setDefaultEncoding(String.valueOf(StandardCharsets.UTF_8));
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        // cfg4StringTemplate
        cfg4StringTemplate = new Configuration(freeMarkerVersion);
        StringTemplateLoader templateLoader = new StringTemplateLoader();
        cfg4StringTemplate.setTemplateLoader(templateLoader);
        cfg4StringTemplate.setDefaultEncoding(String.valueOf(StandardCharsets.UTF_8));
        cfg4StringTemplate.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        return new FreeMarkerUtil();
    }

    /**
     * getDefinedTemplate
     */
    public Template getDefinedTemplate(final String templateName) throws IOException {
        return cfg.getTemplate(FileUtil.normalize(templateName));
    }

    /**
     * getStringTemplate
     */
    public Template getStringTemplate(final String templateName, final String templateValue) throws IOException {
        return new Template(templateName, templateValue, cfg4StringTemplate);
    }

    /**
     * 解析字符串模板
     */
    public String processStringTemplate(final String templateValue, final Map<String, Object> map) throws IOException, TemplateException {
        StringWriter stringWriter = new StringWriter();
        Template template = this.getStringTemplate("StringTemplate", templateValue);
        template.process(map, stringWriter);
        String result = stringWriter.toString();
        stringWriter.close();
        return result;
    }

    /**
     * 解析模板
     */
    public void processTemplate(final String templateFilePath, final String templateDir, final String outputAbsolutePath, final Map<String, Object> map) {
        /* freemarker模板 */
        if (Constants.FTL.equals(FileUtil.extName(templateFilePath))) {
            Writer writer = null;
            try {
                writer = FileUtil.getWriter(outputAbsolutePath,StandardCharsets.UTF_8,true);
                Template temp = this.getDefinedTemplate(CharSequenceUtil.removePrefix(templateFilePath, templateDir));
                temp.process(map, writer);
            } catch (IOException | TemplateException e) {
                log.error("processTemplate exception",e);
            } finally {
                IoUtil.close(writer);
            }
        } else {
            /* 复制文件 */
            FileUtil.copy(templateFilePath, outputAbsolutePath, true);
        }
    }
}
